package config

import (
	"fmt"
	"github.com/spf13/viper"
	"log"
	"strconv"
)

var defaultPath = "config.yml"

type Config struct {
	FilePath string
	Viper    *viper.Viper
	Conf     Conf
}

type Conf struct {
	Gorm    GormCfg
	Web     WebCfg
	Log     LogCfg
	Gateway Gateway
	Nacos   NacosCfg
}

type Gateway struct {
	Routes []Route
}

type RouteGate struct {
	Gates []*Route
}

type Route struct {
	Id   string
	Url  string
	Ip   string
	Port uint64
}

type GormCfg struct {
	Username         string `mapstructure:"username"`
	Password         string `mapstructure:"password"`
	Dbname           string `mapstructure:"dbname"`
	Address          string `mapstructure:"address"`
	Sqlinitpath      string `mapstructure:"sqlinitpath"`
	Sqlincrementpath string `mapstructure:"sqlincrementpath"`
}

type LogCfg struct {
	Path  string
	Level string
	Name  string
}

type WebCfg struct {
	Port string
}

type ClientConfig struct {
	NamespaceId string `mapstructure:"namespaceId"`
	TimeoutMs   uint64 `mapstructure:"timeoutMs"`
	LogDir      string
	CacheDir    string
	LogLevel    string
}

type ServerConfig struct {
	IpAddr string `mapstructure:"ipaddr"`
	Port   uint64 `mapstructure:"port"`
}

type RegisterConfig struct {
	DataId      string
	ServiceName string
	ClusterName string
	GroupName   string
	Weight      string
}

type NacosCfg struct {
	ClientConfig   ClientConfig
	ServerConfig   ServerConfig
	RegisterConfig RegisterConfig
}

var webCfg = WebCfg{}

var logCfg = LogCfg{}

var gormCfg = GormCfg{}

var gateway = Gateway{}

var routegate = RouteGate{
	Gates: make([]*Route, 0),
}

var RouteMap = make(map[string]*Route)
var ConfigAll = Conf{}

//加载配置
func LoadConfig(path string) *Config {
	var cfg *Config
	var cfgPath string
	v := viper.New()
	v.SetConfigType("yml")
	if path == "" {
		cfgPath = defaultPath
	} else {
		cfgPath = path
	}
	v.SetConfigFile(cfgPath)
	// 读取配置文件
	err := v.ReadInConfig()
	if err != nil {
		log.Println("读取配置文件失败, 异常信息 : ", err)
	}
	cfg = &Config{
		FilePath: defaultPath,
		Viper:    v,
	}
	return cfg
}

func Routes() *RouteGate {
	return &routegate
}

func NewRoute() *Route {
	return new(Route)
}

func (cfg *Config) Unmarshal(o interface{}) error {
	return cfg.Viper.Unmarshal(o)
}

//获取字符串类型配置
func (cfg *Config) GetString(key string) string {
	return fmt.Sprintf("%v", cfg.Viper.Get(key))
}

//获取Uint64类型的配置
func (cfg *Config) GetUInt64(key string) uint64 {
	intervalue, err := strconv.Atoi(fmt.Sprintf("%v", cfg.Viper.Get(key)))
	if err != nil {
		panic(err)
	}
	return uint64(intervalue)
}

//获取int类型配置
func (cfg *Config) GetInt(key string) int {
	intervalue, err := strconv.Atoi(fmt.Sprintf("%v", cfg.Viper.Get(key)))
	if err != nil {
		panic(err)
	}
	return intervalue
}
